﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Kpmg.CompanyInfo;

namespace MySearch
{
    public static class UserInfoOM
    {
        #region UserInfo

        public static UserInfo GetUserInfo(string userID)
        {
            if (String.IsNullOrEmpty(userID))
                throw new Exception("UserInfoOM.GetUserInfo::Invalid parameter");

            //Get staff object
            Staff objStaff = StaffDAO.GetObjectByUserId(userID);
            if (objStaff == null)
                throw new Exception("UserInfoOM.GetUserInfo::The object is null");

            //Get Role
            /**
             * 1: if SysAdmin using AppConfigurer
             * 2: if Admin using AppConfigurer
             * 3: if Agent using Agent_Team_Member
             * 4: Default Requestor
             */
            UserInfo userInfo;
            //Agent
            IDictionary<string, TeamRole> dicMember = UserInfoDAO.ListMyTeam(objStaff.StaffNo);
            if (dicMember != null && dicMember.Count > 0)
            {
                IList<string> lstTeam = new List<string>();
                foreach (KeyValuePair<string, TeamRole> kv in dicMember)
                {
                    lstTeam.Add(kv.Key);
                }
                userInfo = new UserInfo(objStaff, UserRole.Agent, lstTeam);
                return userInfo;
            }
            //SysAdmin or Admin
            UserRole? userRole = GetAdminRole(objStaff.StaffNo);
            if (userRole != null)
            {
                userInfo = new UserInfo(objStaff, (UserRole)userRole, new List<string>());
                return userInfo;
            }

            //Default
            userInfo = new UserInfo(objStaff, UserRole.Requestor, new List<string>());
            return userInfo;
        }

        public static UserRole? GetAdminRole(string staffNo)
        {
            if (string.IsNullOrEmpty(staffNo))
                throw new Exception("UserInfoOM.GetAdminRole::Invalid parameter");

            IList<string> lstConfig = null;

            lstConfig = AppConfigurer.GetConfig(UserRole.Admin.ToString());
            if (lstConfig != null && lstConfig.Contains(staffNo))
                return UserRole.Admin;

            lstConfig = AppConfigurer.GetConfig(UserRole.SysAdmin.ToString());
            if (lstConfig != null && lstConfig.Contains(staffNo))
                return UserRole.SysAdmin;

            return null;
        }

        #endregion

        #region AgentTeam

        public static AgentTeam GetTeam(string teamCode)
        {
            if (String.IsNullOrEmpty(teamCode))
                throw new Exception("UserInfoOM.GetTeam::Invalid parameter");

            return UserInfoDAO.GetAgentTeam(teamCode);
        }

        public static bool CheckTeamNameCode(string teamCode)
        {
            if (string.IsNullOrEmpty(teamCode))
                throw new Exception("UserInfoOM.GetTeam::Invalid parameter");

            return UserInfoDAO.CheckTeamNameCode(teamCode);
        }

        public static IList<AgentTeam> ListTeam()
        {
            return UserInfoDAO.ListAgentTeam();
        }

        public static void AddAgentTeam(string teamCode, string teamName, string office, bool isSystem, TeamStatus status, string oper)
        {
            if (String.IsNullOrEmpty(teamCode) || string.IsNullOrEmpty(teamName) || string.IsNullOrEmpty(office) || string.IsNullOrEmpty(oper))
                throw new Exception("UserInfoOM.AddAgentTeam::Invalid parameter");

            if (UserInfoDAO.CheckTeamNameCode(teamCode))
                throw new Exception("UserInfoOM.AddAgentTeam::Object exist");

            UserInfoDAO.CreateAgentTeam(teamCode, teamName, office, isSystem, status);
            LogUtil.LogEvent(teamCode, EventAction.CreateTeam, oper, "name:" + teamName + ",office:" + office + ",IsSystem:" + isSystem + ",status:" + status);
        }

        public static void DeleteTeam(string teamCode, string oper)
        {
            if (string.IsNullOrEmpty(teamCode) || string.IsNullOrEmpty(oper))
                throw new Exception("UserInfoOM.DeleteTeam::Invalid parameter");

            AgentTeam team = UserInfoDAO.GetAgentTeam(teamCode);
            if (team == null)
                throw new Exception("UserInfoOM.DeleteTeam::The object is null");


            if (team != null && team.Members.Count < 1 && team.ServiceTypeCodes.Count < 1)
            {
                UserInfoDAO.DeteleAgentTeam(teamCode);
                LogUtil.LogEvent(teamCode, EventAction.DeleteTeam, oper, "");
            }
        }

        public static void UpdateAgentTeam(string teamCode, string teamName, string office, bool isSystem, TeamStatus status, string oper)
        {
            if (string.IsNullOrEmpty(teamCode) || string.IsNullOrEmpty(teamName) || string.IsNullOrEmpty(office))
                throw new Exception("UserInfoOM.UpdateAgentTeam::Invalid parameter");

            AgentTeam team = UserInfoDAO.GetAgentTeam(teamCode);
            if (team == null)
                throw new Exception("UserInfoOM.UpdateAgentTeam::The object is null");

            if (FindTeamDifference(team, teamCode, teamName, office, isSystem, status))
            {
                UserInfoDAO.UpdateAgentTeam(teamCode, teamName, office, isSystem, status);
                LogUtil.LogEvent(teamCode, EventAction.UpdateTeam, oper, "name:" + teamName + ",office:" + office + ",IsSystem:" + isSystem + ",status:" + status);
            }
        }

        #endregion

        #region AgentTeamMember

        public static TeamRole? GetTeamRole(string staffNo, string teamCode)
        {
            if (string.IsNullOrEmpty(staffNo) || string.IsNullOrEmpty(teamCode))
                throw new Exception("UserInfoOM.GetTeamRole::Invalid parameter");

            return UserInfoDAO.GetTeamRole(staffNo, teamCode);
        }

        public static bool CheckTeamLeader(string teamCode)
        {
            if (string.IsNullOrEmpty(teamCode))
                throw new Exception("UserInfoOM.CheckTeamLeader::Invalid parameter");

            return UserInfoDAO.CheckTeamLeader(teamCode);
        }

        // return <TeamCode, TeamRole>
        public static IDictionary<string, TeamRole> ListMyTeam(string staffNo)
        {
            if (string.IsNullOrEmpty(staffNo))
                throw new Exception("UserInfoOM.ListMyTeam::Invalid parameter");

            return UserInfoDAO.ListMyTeam(staffNo);
        }

        // return <StaffNo, TeamRole>
        public static IDictionary<string, TeamRole> ListAgentTeamMemberStr(string teamCode)
        {
            if (string.IsNullOrEmpty(teamCode))
                throw new Exception("UserInfoOM.ListAgentTeamMemberStr::Invalid parameter");

            return UserInfoDAO.ListAgentTeamMember(teamCode);
        }

        public static IDictionary<Staff, TeamRole> ListAgentTeamMemberObj(string teamCode)
        {
            if (string.IsNullOrEmpty(teamCode))
                throw new Exception("UserInfoOM.ListAgentTeamMemberObj::Invalid parameter");

            IDictionary<Staff, TeamRole> dicRet = new Dictionary<Staff, TeamRole>();
            IDictionary<string, TeamRole> lst = UserInfoDAO.ListAgentTeamMember(teamCode);

            foreach (KeyValuePair<string, TeamRole> keyPair in lst)
            {
                Staff staff = StaffDAO.GetObject(keyPair.Key);
                if (staff != null && !dicRet.ContainsKey(staff))
                    dicRet.Add(staff, keyPair.Value);
            }

            return dicRet;
        }

        public static void AddTeamMember(string teamCode, string staffNo, TeamRole teamRole, string oper)
        {
            if (GetRole(teamCode, staffNo, oper) != null)
                throw new Exception("UserInfoOM.AddTeamMember::record exist");

            if (!UserInfoDAO.CheckTeamNameCode(teamCode))
                throw new Exception("UserInfoOM.AddTeamMember::no teamCode");

            UserInfoDAO.CreateTeamMember(teamCode, staffNo, teamRole);
            LogUtil.LogEvent(staffNo, EventAction.CreateTeamMember, oper, "TeamCode:" + teamCode + ", TeamRole:" + teamRole.ToString());
        }

        public static void DeleteTeamMember(string teamCode, string staffNo, string oper)
        {
            if (GetRole(teamCode, staffNo, oper) == null)
                throw new Exception("UserInfoOM.DeleteTeamMember::The object is null");

            UserInfoDAO.DeteleTeamMember(teamCode, staffNo);
            LogUtil.LogEvent(staffNo, EventAction.DeleteTeamMember, oper, teamCode);
        }

        public static void UpdateTeamRole(string teamCode, string staffNo, string oper)
        {
            TeamRole? role = GetRole(teamCode, staffNo, oper);

            if (role == null)
                throw new Exception("UserInfoOM.UpdateTeamRole::The object is null");

            if (role != TeamRole.Leader)
            {
                UserInfoDAO.UpdateTeamRole(staffNo, teamCode, TeamRole.Leader);
                LogUtil.LogEvent(staffNo, EventAction.UpdateToTeamLeader, oper, teamCode);
            }
            else if (role != TeamRole.Member)
            {
                UserInfoDAO.UpdateTeamRole(staffNo, teamCode, TeamRole.Member);
                LogUtil.LogEvent(staffNo, EventAction.UpdateToTeamMember, oper, teamCode);
            }
        }

        #endregion

        #region AgentTeamServiceType

        public static IList<string> ListAgentTeamServiceTypeStr(string teamCode)
        {
            if (string.IsNullOrEmpty(teamCode))
                throw new Exception("UserInfoOM.ListAgentTeamServiceTypeStr::Invalid parameter");

            return UserInfoDAO.ListAgentTeamServiceType(teamCode);
        }

        public static IList<ServiceType> ListAgentTeamServiceType(string teamCode)
        {
            if (string.IsNullOrEmpty(teamCode))
                throw new Exception("UserInfoOM.ListAgentTeamServiceType::Invalid parameter");

            IList<ServiceType> lstServiceType = new List<ServiceType>();

            IList<string> lstServiceTypeCodes = UserInfoDAO.ListAgentTeamServiceType(teamCode);

            foreach (string strTemp in lstServiceTypeCodes)
            {
                //ServiceType st = ServiceTemplateOM.GetServiceType(strTemp);
                //if (st != null)
                //    lstServiceType.Add(st);
            }

            return lstServiceType;
        }

        public static void AddAgentTeamServiceType(string teamCode, string typeCode, string oper)
        {
            if (string.IsNullOrEmpty(teamCode) || string.IsNullOrEmpty(typeCode) || string.IsNullOrEmpty(oper))
                throw new Exception("UserInfoOM.AddAgentTeamServiceType::Invalid parameter");

            if (!UserInfoDAO.CheckTeamNameCode(teamCode))
                throw new Exception("UserInfoOM.AddAgentTeamServiceType::no teamCode");

            IList<string> lstCode = UserInfoDAO.ListAgentTeamServiceType(teamCode);
            if (lstCode != null && lstCode.Contains(typeCode))
                throw new Exception("UserInfoOM.AddAgentTeamServiceType::record exist");

            UserInfoDAO.CreateAgentTeamServiceType(teamCode, typeCode);
            LogUtil.LogEvent(teamCode, EventAction.CreateAgentTeamServiceType, oper, typeCode);

        }

        public static void DeleteAgentTeamServiceType(string teamCode, string typeCode, string oper)
        {
            if (string.IsNullOrEmpty(teamCode) || string.IsNullOrEmpty(typeCode) || string.IsNullOrEmpty(oper))
                throw new Exception("UserInfoOM.DeleteAgentTeamServiceType::Invalid parameter");


            IList<string> lstCode = UserInfoDAO.ListAgentTeamServiceType(teamCode);
            if (lstCode == null || !lstCode.Contains(typeCode))
                throw new Exception("UserInfoOM.DeleteAgentTeamServiceType::The object is null");

            UserInfoDAO.DeteleAgentTeamServiceType(teamCode, typeCode);
            LogUtil.LogEvent(teamCode, EventAction.DeleteAgentTeamServiceType, oper, typeCode);

        }

        #endregion

        #region private

        private static TeamRole? GetRole(string teamCode, string staffNo, string oper)
        {
            if (String.IsNullOrEmpty(teamCode) || string.IsNullOrEmpty(staffNo) || string.IsNullOrEmpty(oper))
                throw new Exception("UserInfoOM.GetRole::Invalid parameter");

            return UserInfoDAO.GetTeamRole(staffNo, teamCode);
        }

        private static bool FindTeamDifference(AgentTeam team, string teamCode, string teamName, string office, bool isSystem, TeamStatus status)
        {
            if (team == null)
                return false;

            if (team.Code.Equals(teamCode) && team.Name.Equals(teamName) && team.Office.Equals(office) && team.IsSystem == isSystem && team.status == status)
                return false;

            return true;
        }

        #endregion
    }

}